/*
	ViewConnectServer.cpp
	(c)2000 Palestar, Richard Lyle
*/

#define INTERFACE_DLL
#include "Debug/Assert.h"
#include "Render3d/NodeSound.h"
#include "Render3d/NodeLight.h"
#include "Game/NounStar.h"
#include "Interface/GameDocument.h"
#include "Interface/ViewConnectServer.h"

//----------------------------------------------------------------------------

IMPLEMENT_FACTORY( ViewConnectServer, WindowView::View );
REGISTER_FACTORY_KEY( ViewConnectServer, 4137065806977686835 );

ViewConnectServer::ViewConnectServer()
{
	// Construct your view class
}

//----------------------------------------------------------------------------

void ViewConnectServer::onActivate()
{
	GameDocument * pDoc = (GameDocument *)document();
	ASSERT( pDoc );

	//{{BEGIN_DATA_INIT
	m_pProgress = dynamic_cast<WindowBar *>( window()->findNode( "Progress" ) );
	m_pStatus = dynamic_cast<WindowText *>( window()->findNode( "Status" ) );
	//END_DATA_INIT}}

	// called when this view is created
	m_pStatus->setText( CharString().format("Connected to %s...\nLoading Objects...", pDoc->client()->serverStatus().name) );
	m_pProgress->setPosition( 0.0f );

	GameContext * pContext = pDoc->context();
	ASSERT( pContext );

	m_PreCache.release();
	m_PreCacheIndex = 0;

	// pre-cache all universe objects (i.e. planets, stars, moons, etc..)
	SortedArray< WidgetKey > cacheOnce;
	for(int z=0;z<pContext->zoneCount();z++)
	{
		NodeZone * pRoot = pContext->zone( z );
		for(int i=0;i<pRoot->childCount();i++)
		{
			BaseNode * pChild = pRoot->child(i);
			if ( dynamic_cast<NounPlanet *>( pChild ) || dynamic_cast<NounStar *>( pChild ) )
			{
				NounContext * pNounContext = ((Noun *)pChild)->nounContext();
				if ( pNounContext == NULL )
					continue;
				if ( cacheOnce.find( pNounContext->key() ) >= 0 )
					continue;
				cacheOnce.insert( pNounContext->key() );

				m_PreCache.push( (Noun *)pRoot->child(i) );
			}
		}
	}

	//// pre-cache all ship types
	//for(int i=0;i<pContext->teamCount();i++)
	//{
	//	Collection::Link pTemplates = pContext->teamN( i ).pTemplates;
	//	if ( ! pTemplates.valid() )
	//		continue;
	//	pTemplates->load();

	//	for(int k=0;k<pTemplates->resourceCount();k++)
	//	{
	//		NounTemplate::Link pShipContext = pTemplates->resource( k );
	//		if ( pShipContext.valid() )
	//		{
	//			if ( cacheOnce.find( pShipContext->key() ) >= 0 )
	//				continue;
	//			cacheOnce.insert( pShipContext->key() );

	//			NounShip * pShip = WidgetCast<NounShip>( pShipContext->noun() );
	//			if (! pShip )
	//				continue;
	//			m_PreCache.push( pShip );

	//			if ( pShip->destroyEffect() )
	//				m_PreCache.push( pShip->destroyEffect()->node() );

	//			// pre-cache all ship gadget effects
	//			for(int j=0;j<pShip->childCount();j++)
	//				if ( dynamic_cast<NounGadget *>( pShip->child(j) ) )
	//				{
	//					NounGadget * pGadget = (NounGadget *)pShip->child(j);

	//					if ( pGadget->useEffect() )
	//						m_PreCache.push( pGadget->useEffect()->node() );
	//					if ( pGadget->projEffect() )
	//						m_PreCache.push( pGadget->projEffect()->node() );
	//					if ( pGadget->hitEffect() )
	//						m_PreCache.push( pGadget->hitEffect()->node() );
	//				}
	//		}
	//	}
	//}

	// hide the cursor
	//setCursor( HIDDEN );
}

void ViewConnectServer::onDeactivate()
{
	// restore the default cursor
	//setCursor( POINTER );
}

void ViewConnectServer::onUpdate( float t )
{
	GameDocument * pDoc = (GameDocument *)document();
	ASSERT( pDoc );

	if ( m_PreCacheIndex < m_PreCache.size() )
	{
		BaseNode * pLoad = m_PreCache[ m_PreCacheIndex++ ];
		ASSERT( pLoad );

		m_pProgress->setPosition( float( m_PreCacheIndex ) / m_PreCache.size() );

		//TRACE( CharString().format("Loading %s", pLoad->name()) );

		// disable sound nodes
		NodeSound::s_bDisable = true;
		NodeLight::s_bDisable = true;

		DisplayDevice * pDisplay = context()->display();
		ASSERT( pDisplay );

		pDisplay->lock();

		// create a render context
		RenderContext renderContext;
		renderContext.setDisplay( pDisplay );
		renderContext.setAudio( context()->audio() );
		renderContext.setProjection( RectInt( 0, 0, 100, 100 ), PI / 4, 1.0f, 32768.0f );

		pDisplay->flush();
		// render the object directly in front of the camera
		pLoad->render( renderContext, Matrix33( true ), Vector3( 0,0,pLoad->radius() + 1.0f ) );
		// clear the display primitives, never actually render them...
		pDisplay->clear();

		pDisplay->unlock();

		// renable sound nodes
		NodeSound::s_bDisable = false;
		NodeLight::s_bDisable = false;
	}
	else
	{
		GameDocument * pDoc = (GameDocument *)document();
		if ( pDoc->isConnected() )
			pDoc->setScene( "Main" );
		else
			pDoc->setScene( "ServerDisconnect" );

		// release the array
		m_PreCache.release();
	}
}

bool ViewConnectServer::onMessage( const Message & msg )
{
	//{{BEGIN_MSG_MAP
	//END_MSG_MAP}}

	switch( msg.message )
	{
	case HM_KEYDOWN:
		switch( msg.wparam )
		{
		case HK_ESCAPE:
			// abort return to select server screen
			((GameDocument *)document())->client()->close();
			((GameDocument *)document())->setScene( "Lobby" );
			return true;
		case HK_SPACE:
			// skip precache, and jump to main screen
			//if ( ((GameDocument *)document())->client()->loggedIn() )
			//{
			//	((GameDocument *)document())->setScene( "Main" );
			//	m_PreCache.release();
			//}
			return true;
		}
	}

	return false;
}

void ViewConnectServer::onDocumentUpdate()
{
	// document data has changed, update this view if needed
}

//----------------------------------------------------------------------------


